package com.hehongdan.cpp

import kotlinx.coroutines.*
import org.junit.Test
import kotlin.system.measureTimeMillis

/**
 * 测试Kotlin携程。
 *
 * @author HHD
 * @data 20200624
 * @version v20200624
 */
class KotlinCoroutinesTest {

    /**
     * 第一个协程。
     */
    @Test
    fun coroutines1() {
        GlobalScope.launch {
            delay(1000L)
            println("World!")
        }
        println("Hello,")
        Thread.sleep(2000L)
    }

    /**
     * 桥接阻塞与非阻塞的世界。
     */
    @Test
    fun coroutines2() {
        GlobalScope.launch {
            delay(1000L)
            println("world!")
        }
        println("hello,")
        runBlocking {
            delay(2000L)
        }
    }

    /**
     * 桥接阻塞与非阻塞的世界。
     */
    @Test
    fun coroutines3() = runBlocking<Unit> {
        GlobalScope.launch {
            delay(1000L)
            println("world!")
        }
        println("Hello,")
        delay(2000L)
    }

    /**
     * 等待一个作业。
     */
    @Test
    fun coroutines4() = runBlocking {
        val job = GlobalScope.launch {
            delay(1000L)
            println("world!")
        }
        println("Hello,")
        job.join()
    }

    /**
     * 结构化并发。
     */
    @Test
    fun coroutines5() = runBlocking {
        launch {
            delay(1000L)
            println("world!")
        }
        println("Hello,")
    }

    /**
     * 作用域构建器。
     */
    @Test
    fun coroutines6() = runBlocking {
        launch {
            delay(200L)
            println("Task from runBlocking")
        }
        coroutineScope {
            launch {
                delay(500L)
                println("Task from nested launch")
            }
            delay(100L)
            println("Task from coroutine scope")
        }
        println("Coroutine scope is over")
    }

    /**
     * 提取函数重构。
     */
    @Test
    fun coroutines7() = runBlocking {
        launch { doWorld() }
        println("Hello,")
    }

    /**
     * suspend：挂起。
     */
    private suspend fun doWorld() {
        delay(1000L)
        println("world!")
    }


    /**
     * 未同时执行（非并发）。
     */
    @Test
    fun coroutinesAsync0() = runBlocking<Unit> {
        val time = measureTimeMillis {
            val one = doSomethingUsefulOne()
            val two = doSomethingUsefulTwo()
            println("one + two结果是= ${one + two}")
        }
        println("耗时 $time 毫秒")
    }

    /**
     * Async并发。
     */
    @Test
    fun coroutinesAsync() = runBlocking<Unit> {
        val time = measureTimeMillis {
            val one = async { doSomethingUsefulOne() }
            val two = async { doSomethingUsefulTwo() }
            println("one + two结果是= ${one.await() + two.await()}")
        }
        println("耗时 $time 毫秒")
    }

    private suspend fun doSomethingUsefulTwo(): Int {
        delay(1000L)
        return 13
    }

    private suspend fun doSomethingUsefulOne(): Int {
        delay(1000L)
        return 29
    }

}

